package com.knife.oauth.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.knife.common.exception.CommonException;
import com.knife.common.tree.builder.impl.DefaultKnifeTreeBuilder;
import com.knife.common.utils.KnifeCommonConverter;
import com.knife.lov.infra.annotations.KnifeProcessLovValue;
import com.knife.oauth.api.vo.IamMenuTree;
import com.knife.oauth.app.service.IamMenuService;
import com.knife.oauth.domain.entity.IamMenu;
import com.knife.oauth.domain.entity.IamRoleMenu;
import com.knife.oauth.infra.mapper.IamMenuMapper;
import com.knife.oauth.infra.mapper.IamRoleMenuMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单权限表(IamMenu)应用服务
 *
 * @author tianhao.luo@hand-china.com
 * @since 2025-08-13 14:19:32
 */
@Service
public class IamMenuServiceImpl implements IamMenuService {
    @Resource
    private IamMenuMapper iamMenuMapper;
    @Resource
    private IamRoleMenuMapper iamRoleMenuMapper;

    @Override
    @KnifeProcessLovValue
    public List<IamMenuTree> selectTree(Long tenantId) throws IllegalAccessException {
        LambdaQueryWrapper<IamMenu> iamMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        iamMenuLambdaQueryWrapper.eq(IamMenu::getType,0)
                .orderByAsc(IamMenu::getSort);
        List<IamMenu> iamMenus = iamMenuMapper.selectList(iamMenuLambdaQueryWrapper);
        return this.buildTree(iamMenus);
    }

    @Override
    public List<IamMenuTree> buildTree(List<IamMenu> iamMenus) throws IllegalAccessException {
        DefaultKnifeTreeBuilder<IamMenu, IamMenuTree> treeBuilder = new DefaultKnifeTreeBuilder<>(item -> KnifeCommonConverter.beanConvert(IamMenuTree.class, item));
        return treeBuilder.buildMultiRootTree(iamMenus);
    }

    @Override
    public IamMenu saveOrUpdateMenu(IamMenu iamMenu) {
        if (Objects.isNull(iamMenu.getId())){
            // 表示需要新增
            iamMenuMapper.insert(iamMenu);
        }else {
            IamMenu db = iamMenuMapper.selectById(iamMenu.getId());
            db.setParentId(iamMenu.getParentId());
            db.setPath(iamMenu.getPath());
            db.setComponent(iamMenu.getComponent());
            db.setName(iamMenu.getName());
            db.setTitle(iamMenu.getTitle());
            db.setIcon(iamMenu.getIcon());
            db.setSort(iamMenu.getSort());
            db.setHidden(iamMenu.getHidden());
            db.setType(iamMenu.getType());
            iamMenuMapper.updateById(db);
        }
        return iamMenu;
    }

    @Override
    public IamMenu deleteMenu(IamMenu iamMenu) {
        // 如果包含子级菜单，不允许删除
        LambdaQueryWrapper<IamMenu> iamMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        iamMenuLambdaQueryWrapper.eq(IamMenu::getParentId,iamMenu.getId()).eq(IamMenu::getType,0);
        Long sonCount = iamMenuMapper.selectCount(iamMenuLambdaQueryWrapper);
        if (sonCount > 0 ){
            throw new CommonException("请先删除子级菜单再操作");
        }
        // 删除菜单及相关按钮
        IamMenu db = iamMenuMapper.selectById(iamMenu.getId());
        LambdaQueryWrapper<IamMenu> iamMenuButtonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        iamMenuButtonLambdaQueryWrapper.eq(IamMenu::getParentId,iamMenu.getId()).eq(IamMenu::getType,1);
        List<IamMenu> iamMenus = iamMenuMapper.selectList(iamMenuButtonLambdaQueryWrapper);
        List<Long> buttonIdList = iamMenus.stream().map(IamMenu::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(buttonIdList)){
            iamMenuMapper.deleteBatchIds(buttonIdList);
        }
        // 删除菜单和角色关联
        LambdaQueryWrapper<IamRoleMenu> iamRoleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        iamRoleMenuLambdaQueryWrapper.eq(IamRoleMenu::getMenuId,iamMenu.getId()).eq(IamRoleMenu::getTenantId, iamMenu.getTenantId());
        List<IamRoleMenu> iamRoleMenus = iamRoleMenuMapper.selectList(iamRoleMenuLambdaQueryWrapper);
        List<Long> roleMenuIdList = iamRoleMenus.stream().map(IamRoleMenu::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(roleMenuIdList)){
            iamRoleMenuMapper.deleteBatchIds(roleMenuIdList);
        }
        iamMenuMapper.deleteById(db);
        return db;
    }
}

